package com.chang.gulimall_auth.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.chang.common.utils.R;
import com.chang.common.vo.MemberResponseVo;
import com.chang.gulimall_auth.feign.MemberFeignServer;
import com.chang.gulimall_auth.vo.GiteeUserInfo;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.HashMap;
import java.util.Map;

/**
 * @author: changzhenxi
 * @date: 2024年12月04日 14:29
 * @Version: 1.0
 * @description:
 */
@Slf4j
@Controller
public class Oauth2Controller {

    @Autowired
    MemberFeignServer memberFeignServer;

    @GetMapping("oauth2.0/gitee/success")
    public String gitee(@RequestParam("code") String code, HttpSession session, HttpServletResponse servletResponse) {
        log.info("code = > {}", code);

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("code", code);
        paramMap.put("grant_type", "authorization_code");
        paramMap.put("client_id", "41ab9639614bb438ce2388e89640a9a6c042bef77515ae292580ad3e3ad1d00a");
        paramMap.put("client_secret", "42ce75d1f84feb7ee9e37d6111830431504363e7f4639815644fd2f567a8ac1a");
        paramMap.put("redirect_uri", "http://auth.gulimall.com/oauth2.0/gitee/success");
        // 封装参数向第三方平台发送请求 根据code换取gitee平台返回的access_token
        String response = HttpUtil.post("https://gitee.com/oauth/token", paramMap);
        log.info("gitee平台response = {}", response);

        Map<String, String> responseMap = JSONUtil.toBean(response, Map.class);
        String access_token = responseMap.get("access_token");
        if (StrUtil.isNotBlank(access_token)) {
            paramMap.clear(); // 前面的数据用一次就够了，目的只为了拿到access_token，然后再凭借access_token获取用户信息
            paramMap.put("access_token", access_token);
            String userInfoResponse = HttpUtil.get("https://gitee.com/api/v5/user", paramMap);

            GiteeUserInfo giteeUserInfo = JSONUtil.toBean(userInfoResponse, GiteeUserInfo.class);

            giteeUserInfo.setExpires_in(String.valueOf(responseMap.get("expires_in")));
            giteeUserInfo.setAccess_token(access_token);
            giteeUserInfo.setLogin(giteeUserInfo.getLogin().replace("-", "_"));

            log.info("封装gitee平台账号用户信息giteeUserInfo = {}", giteeUserInfo);
            R oauthLogin = memberFeignServer.authLogin(giteeUserInfo);
            if (oauthLogin.getCode() == 0) {
                // 登录成功就跳回首页   MemberResponseVo这个vo对象原本是解耦后单独存放在各个模块中，但是这样的话序列化存到redis中就会导致其他微服务无法反序列化，所以都放在common模块中了
                MemberResponseVo memberResponseVo = JSONUtil.toBean(oauthLogin.getData(), MemberResponseVo.class);
                // 第一次使用session 为了解决session跨域问题,在发送session的时候直接指定作用域为父域名(gulimall.com) 而不是子域名(auth/order.gulimall.com)
                // 注意这里想要将内存对象存到session中然后放到redis中 所以就需要先序列化为一个二进制流，就必须要对象实现Serializable序列化接口
                session.setAttribute("loginUser", memberResponseVo);

                // Cookie cookie = new Cookie("jsession", "aaaa");
                // cookie.setDomain("gulimall.com");
                // servletResponse.addCookie(cookie);
                log.info("登录成功memberResponseVo = {}", memberResponseVo.toString());
                return "redirect:http://gulimall.com";
            } else {
                return "redirect:http://auth.gulimall.com/login.html";
            }
        } else {
            // 授权登录失败就重定向到登录平台
            return "redirect:http://auth.gulimall.com/login.html";
        }


    }
}
